#include "GApplication.h"
#include "GSystem.h"
#include "GError.h"
#include "GMessageManager.h"

namespace GEngine
{
	G_MODULE_DESCRIPTOR(GApplication, GModule, NULL);

	GApplication::GApplication()
	{
		Handle = NULL;
		MainWindow = NULL;
	}

	GApplication::~GApplication()
	{
	}

	void* GApplication::GetHandle() const
	{
		return Handle;
	}

	const char* GApplication::GetAppName() const
	{
		return Descriptor()->GetName();
	}

	void GApplication::AppendWindow(GWindow* Window)
	{
		WindowArray::iterator Iter;
		Iter = std::find(Windows.begin(), Windows.end(), Window);

		// If does not contain
		if (Iter == Windows.end())
		{
			Windows.push_back(Window);
		}
	}

	void GApplication::RemoveWindow(GWindow* Window)
	{
		WindowArray::iterator Iter;
		Iter = std::find(Windows.begin(), Windows.end(), Window);
		
		// If contains
		if (Iter != Windows.end())
		{
			Windows.erase(Iter);
		}
	}

	GSize GApplication::GetWindowCount() const
	{
		return Windows.size();
	}

	GWindow* GApplication::GetWindowByIndex(GSize Index) const
	{
		GUtil::GError::DebugCheck(Index >= Windows.size(), "Index out of range.");

		return Windows[Index];
	}

	GWindow* GApplication::FindWindowByHandle(void* Handle)
	{
		GSize Count = Windows.size();
		for (GSize I = 0; I < Count; ++I)
		{
			GWindow* Window = Windows[I];
			if (Window->GetHandle() == Handle)
			{
				return Window; 
			}
		}

		return NULL;
	}

	bool GApplication::Initialize() OVERRIDE
	{
		if (!GModule::Initialize())
		{
			return false;
		}

		bool Result = false;

		// Get HINSTANCE
		Handle = GUtil::GSystem::GetInstance(NULL);

		// Create main window
		MainWindow = new GWindow();
		Result = MainWindow->Create(40, 40, 800, 600, "MainWindow");
		GUtil::GError::DebugCheck(!Result, "Cannot create main window.");

		AppendWindow(MainWindow);


		return true;
	}

	void GApplication::Uninitialize() OVERRIDE
	{
		RemoveWindow(MainWindow);
		MainWindow->Release();
		G_DELETE(MainWindow);

		Handle = NULL;

		Windows.clear();

		GModule::Uninitialize();
	}
}